Capturing Apache response
am 08.02.2009 22:59:24 von Solutio at GmailThis is a multi-part message in MIME format.
------=_NextPart_000_00D8_01C98A06.367C4340
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
We are trying to implement a solution that would allow us to capture =
Apache (v. 2.0.63) responses sent to clients, each in a separate file on =
the server. I added a bucket brigade based output filter that mimics an =
example found in =
http://perl.apache.org/docs/2.0/user/handlers/filters.html#B ucket_Brigade=
_based_Output_Filters, as follows:
____
package httpd::FilterCaptureResponse;
use strict;
use warnings FATAL =3D> 'all';
use base qw(Apache2::Filter);
use Apache2::RequestRec ();
use APR::Table ();
use APR::Bucket ();
use APR::Brigade ();
use Apache2::Const -compile =3D> qw(OK);
use APR::Const -compile =3D> ':common';
sub handler {
my ($filter, $bb) =3D @_;
my $ctx =3D $filter->ctx;
my $data =3D exists $ctx->{data} ? $ctx->{data} : '';
$ctx->{invoked}++;
my ($bdata, $seen_eos) =3D flatten_bb($bb);
# $bdata =3D~ s/-//g;
$data .=3D $bdata if $bdata;
if ($seen_eos) {
my $r_headers =3D $filter->r->headers_out;
use Data::Dumper; # DEBUG
warn "Dumping Apache response headers:\n"; # DEBUG
warn Dumper($r_headers); # DEBUG
if ($data) {
if (open(CAPTION, ">/tmp/ApacheResponse.txt")) {
print CAPTION $data;
close CAPTION;
}
else { warn "Unable to open caption file: $!\n" }
$filter->print($data);
}
}
else {
# store context for all but the last invocation
$ctx->{data} =3D $data;
$filter->ctx($ctx);
}
return Apache2::Const::OK;
}
sub flatten_bb {
my ($bb) =3D shift;
my $seen_eos =3D 0;
my @data;
for (my $b =3D $bb->first; $b; $b =3D $bb->next($b)) {
$seen_eos++, last if $b->is_eos;
$b->read(my $bdata);
push @data, $bdata;
}
return (join('', @data), $seen_eos);
}
1;
-----
It works fine for the response body, but doesn't get the headers. The =
document I mentioned says that headers can only be seen by connection =
filters, so apparently the log contains the empty hash
$VAR1 =3D bless( {}, 'APR::Table' );
I wonder if there is a workaround for this without adding a connection =
filter?
Another question is what the best way would be to pass on arguments to =
the filter so that we could tell it where to store the response?
Thank you in advance.
------=_NextPart_000_00D8_01C98A06.367C4340
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
content=3Dtext/html;charset=3Diso-8859-1>